/*
 * Copyright (c) 2010, okazoh_tk. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *  - Neither the name of the copyright holder nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "DiceScene.h"

using namespace alkes;

const char* DICE_TEXTURE_PATH = "dice.png";

DiceScene::DiceScene()
{
}

DiceScene::DiceScene(IGraphics* graphics)
{
    construct(graphics);
}

DiceScene::~DiceScene()
{
}

void DiceScene::construct(IGraphics* graphics)
{
    if (initDiceObject(graphics, object_))
    {
        addChild(&object_);

        // set camera
        setPerspective(45.f, 4.f/3.f, 1.f, 0.f);
        setLookAt(
            UVector3D(1.f, 2.f, 4.f),
            UVector3D(0.f, 0.f, 0.f),
            UVector3D(0.f, 1.f, 0.f));
    }
}

bool DiceScene::initDiceObject(IGraphics* graphics, Object3D& object)
{
    IGraphics3D* g = static_cast<IGraphics3D*>(graphics);

    // set texture
    TextureResource* tex = registerResource<TextureResource>();
    ImageBuffer* ib = g->decodeImage(DICE_TEXTURE_PATH);
    if (!ib)
    {
        AL_WARN("Failed to decode image %s.", DICE_TEXTURE_PATH);
        return false;
    }

    *tex = ib;

    // 400x300
    // set vertex
    IVertexBuffer* vbuffer = g->createVertexBuffer(AL_VERTEX_XYZ | AL_VERTEX_UV1);
    if (!vbuffer)
    {
        AL_WARN("Failed to create vertex buffer.");
        return false;
    }

#define PX (0.5f)
    Vector3D v[] = {
        {-PX, PX, PX},{ PX, PX, PX},{-PX,-PX, PX},{ PX, PX, PX},{ PX,-PX, PX},{-PX,-PX, PX}, // 1
        {-PX, PX, PX},{-PX, PX,-PX},{ PX, PX, PX},{ PX, PX, PX},{-PX, PX,-PX},{ PX, PX,-PX}, // 2
        {-PX, PX, PX},{-PX,-PX, PX},{-PX, PX,-PX},{-PX,-PX, PX},{-PX,-PX,-PX},{-PX, PX,-PX}, // 3
        { PX, PX, PX},{ PX, PX,-PX},{ PX,-PX, PX},{ PX,-PX, PX},{ PX, PX,-PX},{ PX,-PX,-PX}, // 4
        { PX,-PX, PX},{ PX,-PX,-PX},{-PX,-PX, PX},{-PX,-PX, PX},{ PX,-PX,-PX},{-PX,-PX,-PX}, // 5
        { PX, PX,-PX},{-PX, PX,-PX},{-PX,-PX,-PX},{ PX, PX,-PX},{-PX,-PX,-PX},{ PX,-PX,-PX}, // 6
    };
    int32_t num = sizeof(v)/sizeof(v[0]);

    vbuffer->setVertex3D(0, num, v);

    uint16_t w, h;
    ib->getSize(w, h);
    Vector2D t[] = {
        {100.f/w,100.f/h},{200.f/w,100.f/h},{100.f/w,200.f/h},{200.f/w,100.f/h},{200.f/w,200.f/h},{100.f/w,200.f/h}, // 1
        {100.f/w,100.f/h},{100.f/w,  0.f/h},{200.f/w,100.f/h},{200.f/w,100.f/h},{100.f/w,  0.f/h},{200.f/w,  0.f/h}, // 2
        {100.f/w,100.f/h},{100.f/w,200.f/h},{  0.f/w,100.f/h},{100.f/w,200.f/h},{  0.f/w,200.f/h},{  0.f/w,100.f/h}, // 3
        {200.f/w,100.f/h},{300.f/w,100.f/h},{200.f/w,200.f/h},{200.f/w,200.f/h},{300.f/w,100.f/h},{300.f/w,200.f/h}, // 4
        {200.f/w,200.f/h},{200.f/w,300.f/h},{100.f/w,200.f/h},{100.f/w,200.f/h},{200.f/w,300.f/h},{100.f/w,300.f/h}, // 5
        {300.f/w,100.f/h},{400.f/w,100.f/h},{400.f/w,200.f/h},{300.f/w,100.f/h},{400.f/w,200.f/h},{300.f/w,200.f/h}, // 6
    };
    vbuffer->setTexCoord(0, num, AL_VERTEX_UV1, t);

    VertexResource* vtx = registerResource<VertexResource>();
    *vtx = vbuffer;

//    object.setPrimitiveType(AL_PRIM_TRIANGLE_STRIP);
    object.setPrimitiveType(AL_PRIM_TRIANGLES);
    object.setVertexCount(sizeof(t)/sizeof(t[0]));
    object.setTexture(tex);
    object.setVertex(vtx);

    return true;
}
